Uma árvore de decisão usa a estratégia dividir para conquistar para resolver um problema de decisão. Um problema complexo é dividigo em problemas mais simples, aos quais recursivamente é aplicada a mesma estratégia. As soluções dos subproblemas podem ser combinadas, na forma de uma árvore, para produzir uma solução do problema complexo. A força dessa proposta vem da capacidade de dividir o espaço de instâncias em subespaçõs e cada subespaço é ajustado usando diferentes modelos. Essa é a ideia básica por trás de algoritmos baseados em árvores de decisão, tais como: ID3 (Quinlan, 1979), ASSISTANT (Cestnik et al., 1996), CART (Breiman et al., 1984), C4.5 (Quinlan 1993).
Os modelos em árvore são designados árvores de decisão no caso de problemas de classificação e árvores de regressão nos problemas de regressão.
Formalmente, uma árvore de decisão é um grafo aciclico derecionado em que cada nó é um nó de divisão, com dois ou mais sucessores, ou um nó folha.
Árvores de decisão tem inúmeras vantagens. Elas são um dos algoritmos mais comumente usados, quer em aplicações do mundo real quer no meio acadêmico. Alguns pontos mais positivos referenciados na literatura são:
Flexibilidade
Árvores de decisão não assumem nenhuma distribuição para os dados. Elas são métodos não paramétricos. O espaço de objetos é dividido em subespaços, e cada subespaço é ajustado com diferentes modelos. Uma árvore de decisão fornece uma cobertura exautiva do espaço de instâncias. Havendo exemplos suficientes, pode aproximar o erro de Bayes de qualquer função.
Robustez
Árvores univariáveis são invariantes a transformações monótonas (estritamente) de variavéis de entrada.
Seleção de atributos
O processo de uma árvore de decisão seleciona os atributos a usar no modelo de decisão. Essa seleção de atributos produz modelos que tendem a ser bastante robustos contra a adição de atributos irrelevantes e redundantes.
Interpretabilidade
Decisões complexas e globais podem ser aproximadas por uma série de decisões mais simples e locais. Todas as decisões são baseadas nos valores dos atributos usados para descrever o problema. Ambos os aspectos contribuem para a popularidade das árvores de decisão.
Eficiência
O algoritmo para aprendizado de árvore de decisão é um algoritmo guloso que é construido de cima para baixo (top-down), usando uma estrátegia dividir para conquistar sem backtraking. Sua complexidade de tempo é linear com o número de exemplos.
Apesar das vantagens já mencionadas, alguns problemas conhecidos referenciados na literatura de AM incluem:
Replicação
Valores ausentes
Atributos contínuos
Instabilidade
In [14]:
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import export_graphviz
#!pip install pydot
#!pip install graphviz
import pydot
import graphviz
In [15]:
instances = [
{'Melhor Amigo': False, 'Especie': 'Cachorro'},
{'Melhor Amigo': True, 'Especie': 'Cachorro'},
{'Melhor Amigo': True, 'Especie': 'Gato'},
{'Melhor Amigo': True, 'Especie': 'Gato'},
{'Melhor Amigo': False, 'Especie': 'Gato'},
{'Melhor Amigo': True, 'Especie': 'Gato'},
{'Melhor Amigo': True, 'Especie': 'Gato'},
{'Melhor Amigo': False, 'Especie': 'Cachorro'},
{'Melhor Amigo': True, 'Especie': 'Gato'},
{'Melhor Amigo': False, 'Especie': 'Cachorro'},
{'Melhor Amigo': False, 'Especie': 'Cachorro'},
{'Melhor Amigo': False, 'Especie': 'Gato'},
{'Melhor Amigo': True, 'Especie': 'Gato'},
{'Melhor Amigo': True, 'Especie': 'Cachorro'}
]
In [16]:
df = pd.DataFrame(instances)
df
Out[16]:
In [17]:
X_train = [[1] if x else [0] for x in df['Melhor Amigo']]
Y_train = [1 if y == 'Cachorro' else 0 for y in df['Especie']]
labels = ['Melhor Amigo']
In [18]:
print(X_train)
print(Y_train)
In [19]:
clf = DecisionTreeClassifier(max_depth= None,
max_features = None,
criterion = 'entropy',
min_samples_leaf = 1,
min_samples_split = 2)
In [20]:
clf.fit(X_train, Y_train)
Out[20]:
In [21]:
output = '/home/avinicius/workspace/machine-learning/tree.dot'
In [22]:
export_graphviz(clf, out_file= output, feature_names= labels)
with open(output) as file:
dot_graph = file.read()
graphviz.Source(dot_graph)
Out[22]:
In [ ]:
#!dot -Tpng tree.dot -o tree.png